TODO: Fix problems
In [16]:
%matplotlib inline
In [17]:
from ipywidgets.widgets import Image
from IPython.display import display, display_svg, display_png
In [18]:
# xxxxxxxxxx Add the parent folder to the python path. xxxxxxxxxxxxxxxxxxxx
import sys
parent_dir = "../"
sys.path.append(parent_dir)
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# xxxxxxxxxx Import Statements xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
from time import time
from time import sleep
import numpy as np
from pprint import pprint
from matplotlib import pyplot as plt
from pyphysim.simulations.runner import SimulationRunner
from pyphysim.simulations.parameters import SimulationParameters
from pyphysim.simulations.results import SimulationResults, Result
from pyphysim.simulations.simulationhelpers import simulate_do_what_i_mean
from pyphysim.simulations.runner import get_common_parser
from pyphysim.modulators.fundamental import PSK
from pyphysim.channels import pathloss
from pyphysim.channels import multiuser
from pyphysim.util.conversion import dB2Linear, linear2dB
from pyphysim.cell.cell import Cluster
from pyphysim.util import misc
from pyphysim.util.conversion import dBm2Linear
from pyphysim.ia import algorithms
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
In [19]:
multiUserChannel = multiuser.MultiUserChannelMatrix()
#ia_solver = algorithms.MMSEIASolver(multiUserChannel)
ia_solver = algorithms.MaxSinrIASolver(multiUserChannel)
#ia_solver = algorithms.AlternatingMinIASolver(multiUserChannel)
ia_solver.max_iterations = 500
modulator = PSK(4)
include_path_loss_bool = True
M = 4
NSymbs = 100
K = 19
Nr = 4
Nt = 8
Ns = 2
SNR = 30.0
users_per_cell = 1
# Cluter variables
cell_radius = 1.0
# Dependent parameters
#noise_var = 1 / dB2Linear(SNR)
noise_var = dBm2Linear(-116.4)
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# xxxxxxxxxx Create the cluster of cells xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
cluster = Cluster(cell_radius=cell_radius, num_cells=19)
cluster.create_wrap_around_cells(include_users_bool=True)
cluster.add_random_users(cell_ids=range(1,20), num_users=users_per_cell)
#cluster.add_border_users(cell_ids=range(1,20), angles=0, ratios=0.01)
cluster.figsize = (7,7)
cluster.fill_face_bool = True
cluster.fill_opacity = 0.3
cluster
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Out[19]:
In [20]:
multiUserChannel.randomize(Nr, Nt, K)
if include_path_loss_bool is True:
# xxxxxxxxxx Calculate the pathloss for each link xxxxxxxxxxxxxxxxxxxxx
dists = cluster.calc_dist_all_users_to_each_cell()
#pl_obj = pathloss.PathLossFreeSpace()
pl_obj = pathloss.PathLoss3GPP1()
#pl_obj = pathloss.PathLossOkomuraHata()
# Calculate the path loss in linear scale
pl = pl_obj.calc_path_loss(dists)
#pl = np.eye(19)
multiUserChannel.set_pathloss(pl)
else:
# Path loss will be equal to 1.0 for all links
pl = np.ones([K,K])
multiUserChannel.set_pathloss(None)
In [21]:
# fig, axs = plt.subplots(10,2, figsize=(12,40))
# for row in range(10):
# for col in range(2):
# index = 2 * row + col
# if index > 18:
# break
# # print "{0}: {1}x{2}".format(index, row, col)
# axs[row, col].set_xlim([0, 20])
# axs[row, col].grid()
# axs[row, col].plot(range(1,20), dists[index])
# axs[row, col].plot(index+1, dists[index][index], 'or')
# axs[row, col].xaxis.set_ticks(np.arange(1,20))
# plt.show()
In [22]:
# Calculate the transmit power of each user
snr = dB2Linear(SNR)
Pt = snr * noise_var/pl.diagonal()
In [23]:
pl_dB = -linear2dB(pl)
np.set_printoptions(precision=1, linewidth=140)
for index in range(19):
pl_dB[index] = pl_dB[index] - pl_dB[index][index]
print('Relative Direct Channel Path Loss:\n{0}'.format(pl_dB.diagonal()))
print('Relative Max Path Loss:\n{0}'.format(pl_dB.max(axis=1)))
print('Relative Min Path Loss:\n{0}'.format(np.sort(pl_dB, axis=1)[:,1]))
print()
np.set_printoptions(precision=4, linewidth=120)
# print np.mean(np.sort(pl_dB, axis=1)[:,1])
# print np.mean(pl_dB.max(axis=1))
First we need to ask ourselves what is a good measurement that we can use to say that a interference link is strong enough or not. The easiest one is probably the path loss.
If we count the number of interference links that have a relative path loss when compared with the direct channel of less than 30dB we get
In [24]:
[(sum(pl_dB[i] < 30) - 1) for i in range(19)]
Out[24]:
However, notice that the relative path loss is only one side of the coint. We still need to account the transmit power of each interfering base station when compared with the transmit power of our own base station. That is, if the relative path loss to some interference link is 25dB, but that particular base station transmit with 10dB more power than our own base station then the relative interference power of that link when compared with the desired signal would be 15dB.
In [25]:
noise_var
Out[25]:
In [26]:
assert abs(ia_solver.noise_var - noise_var) < 1e-12
ia_solver.clear()
runned_reps = ia_solver.solve(Ns=Ns, P=Pt)
print(runned_reps)
Some of the precoders may have 0 energy.
In [27]:
data = []
for f in ia_solver.full_F:
data.append(np.linalg.norm(f, 'fro')**2)
print(data[-1])
print
data = np.array(data)
#print("Number of non zero links: {0}".format(len(data[data > 1e-3])))
print("Sum Capacity: {0}\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".format(ia_solver.calc_sum_capacity()))
Pos Processing SINR for each Stream
In [28]:
print("Input SNR: {0}".format(SNR))
print("Post-processing SINRs")
for v in ia_solver.calc_SINR_in_dB():
print(v)
In [29]:
# # If any of the Nr, Nt or Ns variables were integers (meaning all
# # users have the same value) we will convert them by numpy arrays
# # with correct size (K).
# Nr = ia_solver.Nr
# Nt = ia_solver.Nt
# Ns = ia_solver.Ns
# cumNs = np.cumsum(ia_solver.Ns)
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # xxxxx Input Data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # inputData has the data of all users (vertically stacked)
# inputData = np.random.randint(0, M, [np.sum(Ns), NSymbs])
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # xxxxx Modulate input data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # modulatedData has the data of all users (vertically stacked)
# modulatedData = modulator.modulate(inputData)
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # xxxxxxxxxx Perform the Interference Alignment xxxxxxxxxxxxxxxxxxx
# # Split the data. transmit_signal will be a list and each element
# # is a numpy array with the data of a user
# transmit_signal = np.split(modulatedData, cumNs[:-1])
# transmit_signal_precoded = map(np.dot, ia_solver.full_F, transmit_signal)
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # xxxxx Pass through the channel xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# multi_user_channel = ia_solver._multiUserChannel
# # received_data is an array of matrices, one matrix for each receiver.
# #import pudb; pudb.set_trace() ## DEBUG ##
# received_data = multi_user_channel.corrupt_data(
# transmit_signal_precoded, noise_var)
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # xxxxx Perform the Interference Cancelation xxxxxxxxxxxxxxxxxxxxxx
# received_data_no_interference = map(np.dot,
# ia_solver.full_W_H, received_data)
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # xxxxx Demodulate Data xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# received_data_no_interference = np.vstack(received_data_no_interference)
# demodulated_data = modulator.demodulate(received_data_no_interference)
# # demodulated_data = map(modulator.demodulate, received_data_no_interference)
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # xxxxx Calculates the symbol and bit error rates xxxxxxxxxxxxxxxxx
# symbolErrors = np.sum(inputData != demodulated_data)
# bitErrors = misc.count_bit_errors(inputData, demodulated_data)
# numSymbols = inputData.size
# numBits = inputData.size * modulators.level2bits(M)
# ia_cost = ia_solver.get_cost()
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # xxxxxxxxxx Calculates the Sum Capacity xxxxxxxxxxxxxxxxxxxxxxxxxx
# sirn_all_k = ia_solver.calc_SINR()
# calc_capacity = lambda sirn: np.sum(np.log2(1 + sirn))
# # Array with the sum capacity of each user
# sum_capacity = map(calc_capacity, sirn_all_k)
# # Total sum capacity
# total_sum_capacity = np.sum(sum_capacity)
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# #xxxxxxxxxx Number of iterations of the IA algorithm xxxxxxxxxxxxxx
# ia_runned_iterations = ia_solver.runned_iterations
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # Print the results
# print("SumCapacity: {0}".format(total_sum_capacity))
# print("BER: {0}".format(float(bitErrors)/numBits))
# # xxxxx Return the simulation results xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# symbolErrorsResult = Result.create(
# "symbol_errors", Result.SUMTYPE, symbolErrors)
# numSymbolsResult = Result.create(
# "num_symbols", Result.SUMTYPE, numSymbols)
# bitErrorsResult = Result.create("bit_errors", Result.SUMTYPE, bitErrors)
# numBitsResult = Result.create("num_bits", Result.SUMTYPE, numBits)
# berResult = Result.create("ber", Result.RATIOTYPE, bitErrors, numBits,
# accumulate_values=False)
# serResult = Result.create(
# "ser", Result.RATIOTYPE, symbolErrors, numSymbols, accumulate_values=False)
# ia_costResult = Result.create(
# "ia_cost", Result.RATIOTYPE, ia_cost, 1, accumulate_values=False)
# sum_capacityResult = Result.create(
# "sum_capacity", Result.RATIOTYPE, total_sum_capacity, 1,
# accumulate_values=False)
# ia_runned_iterationsResult = Result.create(
# "ia_runned_iterations", Result.RATIOTYPE, ia_runned_iterations, 1, accumulate_values=False)
# #import pudb; pudb.set_trace() ## DEBUG ##
# simResults = SimulationResults()
# simResults.add_result(symbolErrorsResult)
# simResults.add_result(numSymbolsResult)
# simResults.add_result(bitErrorsResult)
# simResults.add_result(numBitsResult)
# simResults.add_result(berResult)
# simResults.add_result(serResult)
# simResults.add_result(ia_costResult)
# simResults.add_result(sum_capacityResult)
# simResults.add_result(ia_runned_iterationsResult)
# # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# # return simResults